﻿Imports Hinshelwood.TFSStickyBuddy.Modules.Interfaces
Imports Microsoft.Practices.Composite.Wpf.Commands
Imports Microsoft.Practices.Composite.Regions
Imports Microsoft.Practices.Composite.Events
Imports Microsoft.Practices.Unity
Imports Microsoft.TeamFoundation.Client
Imports QuantumBitDesigns.Core
Imports System.Collections.ObjectModel
Imports Hinshelwood.TFSStickyBuddy.Infrastructure
Imports System.Threading
Imports Microsoft.TeamFoundation.WorkItemTracking.Client
Imports System.ComponentModel
Imports Hinshelwood.TFSStickyBuddy.Modules.Model
Imports Hinshelwood.TFSStickyBuddy.Infrastructure.Events
Imports Hinshelwood.TFSStickyBuddy.Infrastructure.SyncExtensions

Namespace PresentationModels


    Public Class TeamSystemSelectionPresentationModel
        Implements ITeamSystemSelectionPresentationModel
        Implements INotifyPropertyChanged

        Private ReadOnly m_regionManager As IRegionManager
        Private ReadOnly m_eventAggregator As IEventAggregator
        Private ReadOnly m_TeamServerService As ITeamServerService
        Private ReadOnly m_container As IUnityContainer
        Private ReadOnly m_CredentialProvider As ICredentialProviderPresenter

        Private m_AvailableServers As ObservableList(Of TeamFoundationServer)
        Private m_AvailableProjects As ObservableList(Of Project)
        Private m_SelectedServer As TeamFoundationServer = Nothing
        Private Shared m_IsServerSelected As Boolean = False
        Private m_SelectedProject As Project = Nothing
        Private Shared m_IsProjectSelected As Boolean = False

        Private m_ManageServersCommand As DelegateCommand(Of String)


        Public Property SelectedServer() As TeamFoundationServer Implements ITeamSystemSelectionPresentationModel.SelectedServer
            Get
                Return m_SelectedServer
            End Get
            Set(ByVal value As TeamFoundationServer)
                If Not m_SelectedServer Is value Then
                    m_SelectedServer = value
                    OnPropertyChanged("SelectedServer")
                    SelectedProject = Nothing
                    IsServerSelected = Not m_SelectedServer Is Nothing
                    m_eventAggregator.GetEvent(Of TeamServerSelectionEvent)().Publish(SelectedServer)
                    RefreshProjects()
                End If
            End Set
        End Property

        Public Property IsServerSelected() As Boolean Implements ITeamSystemSelectionPresentationModel.IsServerSelected
            Get
                Return m_IsServerSelected
            End Get
            Set(ByVal value As Boolean)
                If Not m_IsServerSelected = value Then
                    m_IsServerSelected = value
                    OnPropertyChanged("IsServerSelected")
                End If
            End Set
        End Property

        Public Property SelectedProject() As Project Implements ITeamSystemSelectionPresentationModel.SelectedProject
            Get
                Return m_SelectedProject
            End Get
            Set(ByVal value As Project)
                If Not m_SelectedProject Is value Then
                    m_SelectedProject = value
                    OnPropertyChanged("SelectedProject")
                    IsProjectSelected = Not m_SelectedProject Is Nothing
                    m_eventAggregator.GetEvent(Of TeamProjectSelectionEvent)().Publish(SelectedProject)
                End If
            End Set
        End Property

        Public Property IsProjectSelected() As Boolean Implements ITeamSystemSelectionPresentationModel.IsProjectSelected
            Get
                Return m_IsProjectSelected
            End Get
            Set(ByVal value As Boolean)
                If Not m_IsProjectSelected = value Then
                    m_IsProjectSelected = value
                    OnPropertyChanged("IsProjectSelected")
                End If
            End Set
        End Property

        Public ReadOnly Property AvailableServers() As ObservableCollection(Of TeamFoundationServer) Implements ITeamSystemSelectionPresentationModel.AvailableServers
            Get
                Return m_AvailableServers.ObservableCollection
            End Get
        End Property

        Public ReadOnly Property AvailableProjects() As System.Collections.ObjectModel.ObservableCollection(Of Project) Implements Interfaces.ITeamSystemSelectionPresentationModel.AvailableProjects
            Get
                Return m_AvailableProjects.ObservableCollection
            End Get
        End Property

        Public Sub New(ByVal regionManager As IRegionManager, ByVal container As IUnityContainer, ByVal eventAggregator As IEventAggregator, ByVal TeamServerService As ITeamServerService, ByVal CredentialProvider As ICredentialProviderPresenter)
            m_regionManager = regionManager
            m_eventAggregator = eventAggregator
            m_container = container
            m_TeamServerService = TeamServerService
            m_CredentialProvider = CredentialProvider
            ' Commands
            m_ManageServersCommand = New DelegateCommand(Of String)(AddressOf OnManageServersExecuted)
            ' Create 
            m_AvailableServers = New ObservableList(Of TeamFoundationServer)(Application.Current.Dispatcher)
            m_AvailableProjects = New ObservableList(Of Project)(Application.Current.Dispatcher)
        End Sub

        Sub OnManageServersExecuted(ByVal nill As String)
            'Dim addRemoveServerPresenter = m_container.Resolve(Of IAddRemoveServerPresenter)()
            'addRemoveServerPresenter.ManageServers()
            m_eventAggregator.GetEvent(Of NotImplementedEvent)().Publish(New NotImplementedPayload("Manage Servers", Me.GetType, "Use Team Explorer to manage your servers"))
        End Sub


        Public ReadOnly Property ManageServersCommand() As DelegateCommand(Of String) Implements ITeamSystemSelectionPresentationModel.ManageServersCommand
            Get
                Return m_ManageServersCommand
            End Get
        End Property

        Private Sub PopulateAvailableServers_Async()
            Dim refreshList As New Collection(Of TeamFoundationServer)
            For Each teamServer In Microsoft.TeamFoundation.Client.RegisteredServers.GetServers
                Dim linkedTeamServer As New TeamFoundationServer(teamServer.Name, m_CredentialProvider)
                If Not refreshList.Contains(linkedTeamServer) Then
                    refreshList.Add(linkedTeamServer)
                End If
            Next
            m_AvailableServers.Sync(refreshList)
        End Sub

        Public Sub RefreshServers() Implements Interfaces.ITeamSystemSelectionPresentationModel.RefreshServers
            System.Threading.ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf PopulateAvailableServers_Async))
        End Sub

        Private Sub PopulateAvailableProjects_Async()
            If Not SelectedServer Is Nothing Then
                SelectedServer.EnsureAuthenticated()
                Dim x As WorkItemStore = DirectCast(SelectedServer.GetService(GetType(WorkItemStore)), WorkItemStore)
                Dim refreshList As New Collection(Of Project)
                For Each project As Project In x.Projects
                    If Not refreshList.Contains(project) Then
                        refreshList.Add(project)
                    End If
                Next
                m_AvailableProjects.Sync(refreshList)
            End If
        End Sub

        Public Sub RefreshProjects() Implements Interfaces.ITeamSystemSelectionPresentationModel.RefreshProjects
            System.Threading.ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf PopulateAvailableProjects_Async))
        End Sub


#Region " INotifyPropertyChanged "

        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

        Public Sub OnPropertyChanged(ByVal PropertyName As String)
            If Not Application.Current.Dispatcher.CheckAccess Then
                Application.Current.Dispatcher.Invoke(New Action(Of String)(AddressOf OnPropertyChanged), PropertyName)
            End If
            If Not PropertyChangedEvent Is Nothing Then
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName))
                ManageServersCommand.RaiseCanExecuteChanged()
            End If
        End Sub

#End Region


    End Class

End Namespace